////////////////////////////////////////////////////////////////////////////////
// Copyright 2010 Michael Schmalle - Teoti Graphix, LLC
// 
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// 
// http://www.apache.org/licenses/LICENSE-2.0 
// 
// Unless required by applicable law or agreed to in writing, software 
// distributed under the License is distributed on an "AS IS" BASIS, 
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and 
// limitations under the License
// 
// Author: Michael Schmalle, Principal Architect
// mschmalle at teotigraphix dot com
////////////////////////////////////////////////////////////////////////////////

package fxplugins.registry.restricted
{

import fxplugins.plugin.IPluginExtension;
import fxplugins.plugin.PluginOptions;
import fxplugins.registry.IContributor;
import fxplugins.registry.IExtensionRegistry;

public class ExtensionParser
{
	//--------------------------------------------------------------------------
	//
	//  Private Static :: Properties
	//
	//--------------------------------------------------------------------------
	
	private static var logMessages:Boolean = false;
	
	/*
	public static function initializeRegistry(registry:ExtensionRegistry,
											  bundles:Array):void // of IBundleContributor
	{
		var bundle:IBundleContributor;
		
		for each (bundle in bundles) 
		{
			// TODO figure out how bundleID realtes to contributorID,
			// registry needs to be incharge of that number
			var client:IContributor = registry.createContributor(
				bundle.bundleID, bundle.symbolicName);
			
			registry.addContributor(client);
			
			log("   Contributors :: " + client.name);
		}
		
		// now loop through all bundles (now contributors and get their points
		for each (bundle in bundles)
		{
			parseExtensionPoints(registry, bundle);
		}
		
		// now loop through extensions
		for each (bundle in bundles)
		{
			parseExtensions(registry, bundle);
		}
	}
	*/
	
	//--------------------------------------------------------------------------
	//
	//  Private Static :: Methods
	//
	//--------------------------------------------------------------------------
	
	/*
	private static function parseExtensionPoints(registry:ExtensionRegistry,
												 bundle:IBundleContributor):void
	{
		log("ExtensionParser::parseExtensionPoints(" + bundle.symbolicName + ")");
		var bundleContributor:IContributor = registry.getContributor(bundle.bundleID);
		
		var pluginEntry:BundleEntry = bundle.getEntry("component-plugin.xml") as BundleEntry;
		if (pluginEntry) 
		{
			doParseExtensionPoints(registry, new XML(pluginEntry.getBytes()), bundleContributor);
		}
	}
	*/
	
	/*
	private static function doParseExtensionPoints(registry:ExtensionRegistry,
												   plugin:XML,
												   contributor:IContributor):void
	{
		var points:XMLList = plugin['extension-point'];
		
		for each (var point:XML in points)
		{
			var extensionPointID:String = point.@id;
			log("    addExtensionPoint(" + contributor.name + "." + extensionPointID + ")");
			registry.addExtensionPoint(extensionPointID, contributor);
		}
	}
	*/
	
	
	/*
	private static function parseExtensions(registry:ExtensionRegistry,
											bundle:IBundleContributor):void
	{
		log("ExtensionParser::parseExtensions(" + bundle.symbolicName + ")");
		var pluginEntry:BundleEntry = bundle.getEntry("component-plugin.xml") as BundleEntry;
		
		var bundleContributor:IContributor = registry.getContributor(bundle.bundleID);
		
		if (pluginEntry)
		{
			doParseExtension(registry, new XML(pluginEntry.getBytes()), bundleContributor);
		}
	}
	*/
	
	/*
	private static function doParseExtension(registry:ExtensionRegistry,
											 plugin:XML, 
											 contributor:IContributor):void
	{
		var extensions:XMLList = plugin['extension'];
		var newChildren:Array = [];
		
		for each (var extension:XML in extensions) 
		{
			log(" Create Extension(" + extension.@point + ") [" + contributor.name + "]");
			
			var ext:RegistryExtension = registry.addExtension(
				extension.@id, 
				extension.@point, 
				extension.@name, 
				contributor) as RegistryExtension;
			
			ext.children = parseExensionDescriptors(
				registry, extension.children(), contributor, ext.registryID) ;
		}
	}
	*/
	
	/**
	 * Parses an extension.
	 */
	public static function parseExtension(registry:IExtensionRegistry,
										  contributor:IContributor,
										  pluginExtension:IPluginExtension,
										  extensionID:String,
										  extensionPointID:String,
										  extensionName:String):void
	{
		var extension:RegistryExtension = registry.addExtension(
			contributor,
			extensionID, 
			extensionPointID, 
			extensionName) as RegistryExtension;
		
		extension.children = parseExensionDescriptors(
			ExtensionRegistry(registry), Object(pluginExtension).children, 
			contributor, extension.registryID) ;
	}
	
	/**
	 * Parses the children into <code>IExtensionDescriptor</code> instances.
	 */
	public static function parseExensionDescriptors(registry:ExtensionRegistry,
													children:Array, 
													contributor:IContributor, 
													parentID:int):Array
	{
		var newChildren:Array = []; 
		
		for each (var child:PluginOptions in children)
		{
			var properties:Object = child;
			
			var tagName:String = properties.name;
			
			log("    <" + tagName + ">");
			
			for (var name:String in properties)
			{
				log("      name [" + name + "] value [" + properties[name] + "]");
			}
			
			var parent:RegistryExtensionDescriptor = 
				registry.addExtensionDescriptor(
					contributor, parentID, tagName, properties) as RegistryExtensionDescriptor;
			
			if (child.children != null && child.children.length > 0) 
			{
				var subChildren:Array = parseExensionDescriptors(
					registry, 
					child.children, 
					contributor, 
					parent.registryID);
				
				parent.children = subChildren;
			}
			
			newChildren.push(parent.registryID);
		}
		
		return newChildren;
	}
	
	/**
	 * @private
	 */
	public static function parseXMLExensionDescriptors(registry:ExtensionRegistry,
													   children:XMLList, 
													   contributor:IContributor, 
													   parentID:int):Array
	{
		var newChildren:Array = [];
	
		for each (var child:XML in children) 
		{
			var tagName:String = child.name();
			
			log("    <" + tagName + ">" );
			
			var properties:Object = {};
			var xml:XML = child[0];
			var attributes:XMLList = xml.@*;
			
			for each (var attribute:XML in attributes) 
			{
				var qname:QName = attribute.name();
				var value:String = xml[qname];
				log("      name [" + qname.localName + "] value [" + value + "]");
				properties[qname.localName] = value;
			}
			
			var parent:RegistryExtensionDescriptor = 
				registry.addExtensionDescriptor(
					contributor, parentID, tagName, properties) as RegistryExtensionDescriptor;
			
			if (child.children().length() > 0) 
			{
				var subChildren:Array = parseXMLExensionDescriptors(
					registry, 
					child.children(), 
					contributor, 
					parent.registryID);
				
				parent.children = subChildren;
			}
			
			newChildren.push(parent.registryID);
		}
		
		return newChildren;
	}
	
	private static function log(message:String):void
	{
		if (logMessages)
		{
			trace(message);
		}
	}
}
}